home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 August: Tool Chest / Dev.CD Aug 98 TC.toast / Tool Chest / Testing & Debugging / Virtual User / Virtual User Current Release / Examples / External Tool Templates / C Tool Template / YourTool.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-04  |  20.6 KB  |  932 lines  |  [TEXT/MPS ]

  1. /*
  2.  *    File:        YourTool.c
  3.  *
  4.  *  Note:        We designed this template to work with V.U. 2.0dx.  If you have a more
  5.  *                recent version of V.U., please look for the current version of this file.
  6.  *
  7.  *                To add functionality to this tool, replace all occurrences of 'YourTool'
  8.  *                and 'YourService' with your own names and supply the corresponding code.
  9.  *
  10.  *    Contains:    V.U. 2.0 External Tool C Template.
  11.  *
  12.  *                This program receives and responds to Apple Events using the
  13.  *                V.U. 2.0 external tool Interface protocol. 
  14.  *
  15.  *    Written by:    Automation Systems Team, Apple Computer, Inc.
  16.  *
  17.  */
  18.  
  19.                                         //    Includes
  20. #include <Types.h>
  21. #include <Memory.h>
  22. #include <Packages.h>
  23. #include <Errors.h>
  24. #include <QuickDraw.h>
  25. #include <Fonts.h>
  26. #include <Dialogs.h>
  27. #include <Windows.h>
  28. #include <Menus.h>
  29. #include <Events.h>
  30. #include <OSEvents.h>
  31. #include <Desk.h>
  32. #include <DiskInit.h>
  33. #include <Resources.h>
  34. #include <ToolUtils.h>
  35. #include <AppleEvents.h>
  36. #include <EPPC.h>
  37. #include <GestaltEqu.h>
  38. #include <PPCToolbox.h>
  39. #include <Processes.h>
  40. #include <String.h>
  41. #include <VUAE.h>
  42.  
  43.                                         //     Constants
  44. #define    kMBarID                    128
  45. #define    kAppleMenu                128
  46. #define    kFileMenu                129
  47. #define    kEditMenu                130
  48. #define NIL                        0L
  49. #define TRUE                    1
  50. #define FALSE                    0
  51. #define    kSuspendResumeMessage    1
  52. #define kMouseMovedMessage        250
  53.  
  54.                                         //    Your services
  55.  
  56.  OSErr  YourService( AppleEvent msg, AppleEvent reply, long refCon );
  57.  
  58.                                         // VU required services
  59.                                         
  60. pascal    OSErr  VUServiceHandler( AppleEvent msg, AppleEvent reply, long refCon );
  61.  
  62. OSErr  VUInitializeHandler( AppleEvent msg, AppleEvent reply, long refCon );
  63. OSErr  VUCancelHandler( AppleEvent msg, AppleEvent reply, long refCon );
  64. OSErr  VUSrvcListHandler( AppleEvent msg, AppleEvent reply, long refCon );
  65. OSErr  VUVersionHandler( AppleEvent msg, AppleEvent reply, long refCon );
  66. OSErr  VUHasSrvcHandler( AppleEvent msg, AppleEvent reply, long refCon );
  67. OSErr  VUQuitHandler( AppleEvent msg, AppleEvent reply, long refCon );
  68.  
  69. void  AskForMoreTime( short requestedExtraTime, AppleEvent reply );
  70.  
  71.                                         // AppleEvent required services
  72.                                         
  73. pascal    OSErr  AEOpenHandler( AppleEvent msg, AppleEvent reply, long refCon );
  74. pascal    OSErr  AEOpenDocHandler( AppleEvent msg, AppleEvent reply, long refCon );
  75. pascal    OSErr  AEQuitHandler( AppleEvent msg, AppleEvent reply, long refCon );
  76. pascal    OSErr  AEPrintHandler( AppleEvent msg, AppleEvent reply, long refCon );
  77.  
  78.                                         // Support
  79.                                         
  80. void     InitAEStuff(void);
  81. void     InitProgram(void);
  82. void     Idling(void);
  83. void     InvokeDA (MenuHandle theMenu, long theItem);
  84. void     BuildMenuBar(void);
  85. void     MenuCommand (long theCmd);
  86. void     DispatchMouseDown (EventRecord theEvent);
  87. void     DispatchKeyDown (EventRecord theEvent);
  88. void     ActivateWindow (WindowPtr theWindow, Boolean activating);
  89. void     UpdateWindow (WindowPtr theWindow);
  90. void     DiskInserted (long diskInfo);
  91. void     DispatchOSEvent (EventRecord theEvent);
  92. void     DispatchHighEvent (EventRecord theEvent);
  93. pascal  OSErr  VUErrorReply    (AppleEvent *reply, Str255 errorText, OSErr errorNo);
  94. void     ReportError (OSErr err, long where);
  95. void    SrvcError (Str255 msg);
  96.  
  97.                                         //    Globals
  98.  
  99. Boolean            hasAE, quitting, background;
  100. Handle            theMenuBar;
  101. MenuHandle        appleMenu, fileMenu, editMenu;
  102. EventRecord        theEvent;
  103. OSErr            aeError;
  104. Str255            strTemp1, strTemp2;
  105.  
  106.  
  107.                                         //    Service Table definition
  108. typedef struct {
  109.     char*    serviceName;
  110.     OSErr    (*serviceFunction)( AppleEvent, AppleEvent, long );
  111. } ServiceInfo;
  112.  
  113. ServiceInfo    VU_Tool_Services[] = {
  114.     { "Initialize", VUInitializeHandler },
  115.     { "Cancel", VUCancelHandler },
  116.     { "GetToolServices", VUSrvcListHandler },
  117.     { "GetToolVersion", VUVersionHandler },
  118.     { "ServiceSupported", VUHasSrvcHandler },
  119.     { "Quit", VUQuitHandler },
  120. //
  121.     { "YourService", YourService },
  122. };
  123.     
  124. const long    NumberOfServices = (sizeof( VU_Tool_Services ) / sizeof( ServiceInfo ));
  125.  
  126.  
  127. //    ** Functions **
  128. main()
  129. {
  130. //    Main event loop. Just get events, and dispatch them to an
  131. //    appropriate handler until we get the 'quit' command.
  132.  
  133.     InitProgram();
  134.  
  135.     while (!quitting) {
  136.         WaitNextEvent (everyEvent, &theEvent, 30, NIL);
  137.             switch (theEvent.what) {
  138.                 case nullEvent: 
  139.                     Idling(); 
  140.                     break;
  141.                 case mouseDown:
  142.                     DispatchMouseDown(theEvent);
  143.                     break;
  144.                 case keyDown:
  145.                 case autoKey:
  146.                     DispatchKeyDown(theEvent);
  147.                     break;
  148.                 case activateEvt:
  149.                     ActivateWindow((WindowPtr)theEvent.message,
  150.                             (theEvent.modifiers & activeFlag) != 0);
  151.                     break;
  152.                 case updateEvt:
  153.                     UpdateWindow((WindowPtr)theEvent.message);
  154.                     break;
  155.                 case diskEvt:
  156.                     DiskInserted(theEvent.message);
  157.                     break;
  158.                 case osEvt:
  159.                     DispatchOSEvent(theEvent);
  160.                     break;
  161.                 case kHighLevelEvent:
  162.                     DispatchHighEvent(theEvent);
  163.                     break;
  164.             }
  165.     }
  166. }
  167.  
  168.  
  169. OSErr  ExtractShortFromAEList( AEDescList paramList, long index, short* result )
  170. {
  171.     OSErr            aeErr;
  172.     AEKeyword        paramKeyword;
  173.     DescType        actualType;
  174.     Size            actualSize;
  175.  
  176.     aeErr = AEGetNthPtr( ¶mList,
  177.                          index,
  178.                          typeShortInteger,
  179.                          ¶mKeyword,
  180.                          &actualType,
  181.                          (Ptr) result,
  182.                          sizeof( *result ),
  183.                          &actualSize );
  184.     if( aeErr )
  185.     {
  186.         ReportError( aeErr, 13 );
  187.     }
  188.  
  189.     return( aeErr );
  190. }
  191.  
  192. OSErr  ExtractStringFromAEList( AEDescList paramList, long index, char* string)
  193. {
  194.     OSErr            aeErr;
  195.     AEKeyword        paramKeyword;
  196.     DescType        actualType;
  197.     Size            actualSize;
  198.  
  199.     aeErr = AEGetNthPtr( ¶mList,
  200.                          index,
  201.                          typeChar,
  202.                          ¶mKeyword,
  203.                          &actualType,
  204.                          (Ptr) string,
  205.                          255,
  206.                          &actualSize );
  207.     if( aeErr )
  208.     {
  209.         ReportError( aeErr, 13 );
  210.     }
  211.     else
  212.     {
  213.         string[actualSize] = '\0';
  214.     }
  215.  
  216.     return( aeErr );
  217. }
  218.  
  219.  
  220. pascal    OSErr  VUServiceHandler(AppleEvent msg, AppleEvent reply, long refcon)
  221. {
  222.     OSType        vuEventClass;
  223.     OSErr        aeErr;
  224.     Str255        serviceName = "";
  225.     DescType    actualType;
  226.     Size        actualSize;
  227.     long        i;
  228.     
  229.     // Get the AE Service Name
  230.     aeErr = AEGetParamPtr(&msg,
  231.                            kVUAESrvcName,
  232.                            typeChar,
  233.                            &actualType,
  234.                            serviceName,
  235.                            255,
  236.                            &actualSize);
  237.     ReportError(aeErr, 1);
  238.     if( aeErr == noErr )
  239.     {
  240.         serviceName[ actualSize ] = '\0';
  241.     }
  242.     
  243.     vuEventClass = kVUAETool;
  244.     aeErr = AEPutAttributePtr( &reply,
  245.                                keyEventClassAttr,
  246.                                typeType,
  247.                                (Ptr) &vuEventClass,
  248.                                sizeof(OSType));
  249.     if( aeErr )
  250.     {
  251.         ReportError(aeErr, 2);
  252.     }
  253.  
  254.     for( i = 0; i < NumberOfServices; i++ )
  255.     {
  256.         if( !relstring( serviceName, VU_Tool_Services[ i ].serviceName, false, true ) )
  257.         {
  258.             aeErr = (*(VU_Tool_Services[ i ].serviceFunction))( msg, reply, refcon );
  259.             return( aeErr );
  260.         }
  261.     }
  262.     
  263. //    SrvcError( (Str255)serviceName );
  264.     return( errAEUnknownService);
  265. }
  266.  
  267. OSErr  VUInitializeHandler( AppleEvent /* msg */, AppleEvent reply, long /* refCon */ )
  268. {    
  269.     OSErr        aeErr;
  270.     
  271.     aeErr = AEPutParamPtr( &reply,
  272.                            kVUAESrvcResults,
  273.                            typeTrue,
  274.                            NIL,
  275.                            0);
  276.     return( aeErr );
  277. }
  278.  
  279. OSErr  VUCancelHandler( AppleEvent /* msg */, AppleEvent /* reply */, long /* refCon */ )
  280. {
  281.     return noErr;
  282. }
  283.  
  284. OSErr  VUQuitHandler( AppleEvent /* msg */, AppleEvent /* reply */, long /* refCon */ )
  285. {
  286.     quitting = TRUE;
  287.     return noErr;
  288. }
  289.  
  290. OSErr  VUVersionHandler( AppleEvent, AppleEvent reply, long )
  291. {
  292. //    This Service asks an external tool to respond
  293. //    with version information about itself.
  294.     
  295. //    The tool name is used by V.U. 2.0 as the name of a tool as shown to a user.
  296. //    Thus, this should be something descriptive; e.g., 'Screen Capture Tool'.
  297.     
  298. //    The version number is simply a number returned to the caller indicating
  299. //    the version of the tool. A V.U. 2.0 script writer could perhaps use this
  300. //    information in verifying that the current release of an external tool was
  301. //    present.
  302.     
  303. //    The version string simply allows more information to be sent by the external
  304. //    tool. V.U. 2.0 does not use the version string.
  305.     
  306. //    This routine simply stuffs values into
  307. //    the Apple Event reply using Apple Event Manager routines.
  308.  
  309.     OSErr        aeErr;
  310.     AEDescList    srvcList;
  311.     char*        strPtr;
  312.  
  313.     aeErr = AECreateList( NIL, 0, FALSE, &srvcList );
  314.     if( aeErr )
  315.     {
  316.         ReportError( aeErr, 3 );
  317.         return( aeErr );
  318.     }
  319.  
  320.     
  321.     strPtr = "YourTool";
  322.     aeErr = AEPutPtr( &srvcList,
  323.                       1,
  324.                       typeChar,
  325.                       strPtr,
  326.                       strlen( strPtr ) );
  327.     if( aeErr )
  328.     {
  329.         ReportError( aeErr, 4 );
  330.     }
  331.     else
  332.     {
  333.         strPtr = "2.0";
  334.         aeErr = AEPutPtr( &srvcList,
  335.                           2,
  336.                           typeChar,
  337.                           strPtr,
  338.                           strlen( strPtr ) );
  339.         if( aeErr )
  340.         {
  341.             ReportError( aeErr, 5 );
  342.         }
  343.         else
  344.         {
  345.             strPtr = "2.0 by the Automation Systems Team, Apple Computer, Inc.";
  346.             aeErr = AEPutPtr( &srvcList,
  347.                               3,
  348.                               typeChar,
  349.                               strPtr,
  350.                               strlen( strPtr ) );
  351.             if( aeErr )
  352.             {
  353.                 ReportError( aeErr, 6 );
  354.             }
  355.             else
  356.             {
  357.                 aeErr = AEPutKeyDesc( &reply,
  358.                                       kVUAESrvcResults,
  359.                                       &srvcList );
  360.                 if( aeErr )
  361.                 {
  362.                     ReportError( aeErr, 7 );
  363.                 }
  364.             }
  365.         }
  366.     }
  367.  
  368.     AEDisposeDesc( &srvcList );
  369.     return( aeErr );
  370. }
  371.  
  372.  
  373. OSErr  VUHasSrvcHandler( AppleEvent msg, AppleEvent reply, long )
  374. {
  375. //    This Service asks an external tool whether a
  376. //    service with a specific name is supported by the tool.
  377.     
  378. //    The routine first extracts the service name from the Apple Event. If the
  379. //    service name cannot be extracted for some reason from the Apple Event,
  380. //    a standard error reply message is sent back to V.U. 2.0.
  381.     
  382. //    The routine simply returns the AppleEvent standard types 'typeTrue' or
  383. //    'typeFalse' depending on whether the service name is supported by the
  384. //    tool or not. The Apple Event Manager will coerce these standard types
  385. //    into an Apple Event Boolean value if necessary (and requested by V.U. 2.0).
  386.  
  387.     OSErr        aeErr;
  388.     Str255        serviceName;
  389.     long        i;
  390.  
  391.     AEDescList    paramList;
  392.     long        numParams;
  393.     
  394.     
  395.     aeErr = AEGetParamDesc( &msg,
  396.                             kVUAESrvcParameters,
  397.                             typeAEList,
  398.                             ¶mList );
  399.     if( aeErr )
  400.     {
  401.         ReportError( aeErr, 14 );
  402.         return( aeErr );
  403.     }
  404.     
  405.     if( aeErr = AECountItems( ¶mList, &numParams ) )
  406.     {
  407.         ReportError( aeErr, 15 );
  408.     }
  409.     else if( numParams != 1 )
  410.     {
  411.         if( aeErr = VUErrorReply( &reply,
  412.                                 "Incorrect number of parameters supplied!",
  413.                                 errAEWrongParameters ) )
  414.         {
  415.             ReportError( aeErr, 16 );
  416.         }
  417.         aeErr = errAEWrongParameters;
  418.     }
  419.     else if( aeErr = ExtractStringFromAEList( paramList, 1, serviceName ) )
  420.     {
  421.         ReportError( aeErr, 17 );
  422.     }
  423.     
  424.     AEDisposeDesc( ¶mList );
  425.     
  426.     if( aeErr )
  427.     {
  428.         return( aeErr );
  429.     }
  430.  
  431.     for( i = 0; i < NumberOfServices; i++ )
  432.     {
  433.         if( !relstring( serviceName, VU_Tool_Services[ i ].serviceName, false, true ) )
  434.         {
  435.             aeErr = AEPutParamPtr( &reply,
  436.                                    kVUAESrvcResults,
  437.                                    typeTrue,
  438.                                    NIL,
  439.                                    0);
  440.             return( aeErr );
  441.         }
  442.     }
  443.     
  444.     aeErr = AEPutParamPtr( &reply,
  445.                            kVUAESrvcResults,
  446.                            typeFalse,
  447.                            NIL,
  448.                            0);
  449.     if( aeErr )
  450.     {
  451.         ReportError(aeErr, 9);
  452.         return( aeErr );
  453.     }
  454.  
  455.     return(aeErr);
  456. }
  457.  
  458.  
  459. OSErr  VUSrvcListHandler( AppleEvent, AppleEvent reply, long )
  460. {
  461. //    This Service asks an external tool for a list of
  462. //    all service names supported by the tool.
  463.     
  464. //    Remember that Apple Event Lists are all one (1) based; i.e., indexes
  465. //    start from one (not zero).
  466.     
  467. //    The first step creates an Apple Event List descriptor. This is followed by
  468. //    stuffing each service name into the list, starting at index number one.
  469. //    Once the list if filled with the service names, the list itself is inserted
  470. //    into the Apple Event reply.
  471.  
  472.     OSErr        aeErr;
  473.     AEDescList    srvcList;
  474.     char*        strPtr;
  475.     long        i;
  476.  
  477.     aeErr = AECreateList( NIL, 0, FALSE, &srvcList );
  478.     if( aeErr )
  479.     {
  480.         ReportError( aeErr, 10 );
  481.         return( aeErr );
  482.     }
  483.  
  484.     for( i = 0; i < NumberOfServices; i++ )
  485.     {
  486.         strPtr = VU_Tool_Services[ i ].serviceName;
  487.         aeErr = AEPutPtr( &srvcList,
  488.                           i + 1,
  489.                           typeChar,
  490.                           strPtr,
  491.                           strlen( strPtr ) );
  492.         if( aeErr )
  493.         {
  494.             ReportError( aeErr, 11 );
  495.             AEDisposeDesc( &srvcList );
  496.             return( aeErr );
  497.         }
  498.     }
  499.     
  500.     
  501.     aeErr = AEPutKeyDesc( &reply,
  502.                           kVUAESrvcResults,
  503.                           &srvcList );
  504.     if( aeErr )
  505.     {
  506.         ReportError( aeErr, 12 );
  507.     }
  508.     
  509.     AEDisposeDesc( &srvcList );
  510.  
  511.     return( aeErr );
  512. }
  513.  
  514.  
  515. OSErr  YourService( AppleEvent msg, AppleEvent reply, long )
  516. {
  517.     OSErr        aeErr;
  518.     AEDescList    paramList;
  519.     long        numParams;
  520.     short        leftNumber, rightNumber, result;
  521.     
  522.     
  523.     aeErr = AEGetParamDesc( &msg,
  524.                             kVUAESrvcParameters,
  525.                             typeAEList,
  526.                             ¶mList );
  527.     if( aeErr )
  528.     {
  529.         ReportError( aeErr, 14 );
  530.         return( aeErr );
  531.     }
  532.     
  533.     if( aeErr = AECountItems( ¶mList, &numParams ) )
  534.     {
  535.         ReportError( aeErr, 15 );
  536.     }
  537.     else if( numParams != 2 )
  538.     {
  539.         if( aeErr = VUErrorReply( &reply,
  540.                                 "You supplied the wrong number of parameters.",
  541.                                 errAEWrongParameters ) )
  542.         {
  543.             ReportError( aeErr, 16 );
  544.         }
  545.         aeErr = errAEWrongParameters;
  546.     }
  547.     else if( aeErr = ExtractShortFromAEList( paramList, 1, &leftNumber ) )
  548.     {
  549.         ReportError( aeErr, 17 );
  550.     }
  551.     else if( aeErr = ExtractShortFromAEList( paramList, 2, &rightNumber ) )
  552.     {
  553.         ReportError( aeErr, 18 );
  554.     }
  555.     
  556.     AEDisposeDesc( ¶mList );
  557.     
  558.     if( aeErr )
  559.     {
  560.         return( aeErr );
  561.     }
  562.  
  563.     result = leftNumber + rightNumber;
  564.  
  565.     aeErr = AEPutParamPtr( &reply,
  566.                           kVUAESrvcResults,
  567.                           typeShortInteger,
  568.                           (Ptr) &result,
  569.                           sizeof( result ) );
  570.     if( aeErr )
  571.     {
  572.         ReportError( aeErr, 19 );
  573.         return( aeErr );
  574.     }
  575.  
  576.     return( aeErr );
  577. }
  578.  
  579. void AskForMoreTime( short requestedExtraTime, AppleEvent reply )
  580. {
  581.     AppleEvent    moreTimeRequestEvent;
  582.     AppleEvent    dummyReply;
  583.     OSErr        aeErr;
  584.     OSType        vuEventId;
  585.     unsigned long    extraTime;
  586.     
  587.     aeErr = AEDuplicateDesc( &reply, &moreTimeRequestEvent );
  588.     if( aeErr )
  589.     {
  590.         ReportError( aeErr, 50 );
  591.     }
  592.     else
  593.     {
  594.         vuEventId = kVUAEWaitLonger;
  595.         aeErr = AEPutAttributePtr( &moreTimeRequestEvent,
  596.                                    keyEventIDAttr,
  597.                                    typeType,
  598.                                    (Ptr) &vuEventId,
  599.                                    sizeof( OSType ) );
  600.         if( aeErr )
  601.         {
  602.             ReportError( aeErr, 51 );
  603.         }
  604.  
  605.         extraTime = requestedExtraTime;
  606.         aeErr = AEPutParamPtr( &moreTimeRequestEvent, kVUAEWaitAmount, typeMagnitude,
  607.                                 (Ptr)&extraTime, sizeof( extraTime ) );
  608.         if( aeErr )
  609.         {
  610.             ReportError( aeErr, 52 );
  611.         }
  612.         
  613.         aeErr = AESend( &moreTimeRequestEvent,
  614.                         &dummyReply,
  615.                         kAENoReply + kAENeverInteract,
  616.                         kAENormalPriority,
  617.                         kNoTimeOut,
  618.                         NULL,
  619.                         NULL );
  620.         if( aeErr )
  621.         {
  622.             ReportError( aeErr, 53 );
  623.         }
  624.         
  625.         aeErr = AEDisposeDesc( &moreTimeRequestEvent );
  626.         if( aeErr )
  627.         {
  628.             ReportError( aeErr, 54 );
  629.         }
  630.     }
  631. }
  632.  
  633. pascal    OSErr  AEOpenHandler(AppleEvent, AppleEvent, long)
  634. {
  635. //    Standard (empty) handler for the 'oapp' Apple Event. Our program does
  636. //    not need anything special here, so "noErr" can simply be returned.
  637.  
  638.     return(noErr);
  639. }
  640.  
  641.  
  642. pascal    OSErr  AEOpenDocHandler(AppleEvent, AppleEvent, long)
  643. {
  644. //    Standard (empty) handler for the 'odoc' Apple Event. Our program does
  645. //    not have documents, so we ignore this Apple Event.
  646.  
  647.     return(noErr);
  648. }
  649.  
  650.  
  651. pascal    OSErr  AEQuitHandler(AppleEvent, AppleEvent, long)
  652. {
  653. //    Standard handler for the 'quit' Apple Event. You must never, ever call
  654. //    ExitToShell from within an Apple Event handler. It is certain death
  655. //    for your application. Thus, we just set a flag which is examined later
  656. //    in the main event loop.
  657.  
  658.     quitting = TRUE;
  659.     return(noErr);
  660. }
  661.  
  662.  
  663. pascal    OSErr  AEPrintHandler(AppleEvent, AppleEvent, long)
  664. {
  665. //    Standard (empty) handler for the 'pdoc' Apple Event. Our program does
  666. //    not have documents, so we ignore this Apple Event.
  667.  
  668.     return(noErr);
  669. }
  670.  
  671.  
  672. void     ReportError(OSErr err, long where)
  673. {
  674. //    Reports an error by way of an Alert dialog. "err" is the error
  675. //    code. "where" is an arbitrary (but unique) number indicating
  676. //    where in the program the error occurred. Of course, if there
  677. //    is no error, this routine does nothing.
  678.  
  679.     int        dontCare;
  680.     Str255    errStr, whereStr;
  681.  
  682.     if (err != 0) {
  683.         numtostring(err, errStr);
  684.         numtostring(where, whereStr);
  685.         paramtext(errStr, whereStr, '', '');
  686.         dontCare = Alert(128, NIL);
  687.     }
  688. }
  689.  
  690.  
  691. void    SrvcError(Str255 msg)
  692. {
  693. //    Displays an error dialog when the service name sent by V.U. 2.0
  694. //    does not conform to a legal service understood by the external
  695. //    tool. In reality, this program should check the Apple Event
  696. //    user interaction level to determine how (and whether) to interact
  697. //    with the user.
  698.  
  699.     int        dontCare;
  700.  
  701.     paramtext(msg, '', '', '');
  702.     dontCare = Alert(128, NIL);
  703. }
  704.  
  705. pascal  OSErr  VUErrorReply(AppleEvent *reply, Str255 errorText, OSErr errorNo)
  706. {
  707.     OSErr        aeErr;
  708.  
  709.     aeErr = AEPutParamPtr(reply,
  710.                            keyErrorString,
  711.                            typeChar,
  712.                            errorText,
  713.                            strlen(errorText));
  714.     if (aeErr == noErr) {
  715.         aeErr = AEPutParamPtr(reply,
  716.                                keyErrorNumber,
  717.                                typeShortInteger,
  718.                                (Ptr)&errorNo,
  719.                                sizeof(errorNo));
  720.         }
  721.     return(aeErr);
  722. }
  723.  
  724.  
  725. void     InitAEStuff(void)
  726. {
  727. //    Initialization of the Apple Event Manager and dispatch table.
  728. //    If we don't have Apple Events or installation of any of the
  729. //    Apple Event handlers fails, the program is simply terminated.
  730. //    The routine starts by installing standard handlers for the
  731. //    core Apple Events. This is followed by installation of the
  732. //    event handlers for the V.U. 2.0 external tool interface.
  733.  
  734.     long            response;
  735.     OSErr            aeErr;
  736.  
  737.     hasAE = (Gestalt(gestaltAppleEventsAttr, &response) == noErr);
  738.     if (hasAE) {    // Has AE
  739.         aeErr = AEInstallEventHandler(kVUAETool,
  740.                                        kVUAESendService,
  741.                                        (EventHandlerProcPtr) VUServiceHandler,
  742.                                        0, FALSE);
  743.         if (aeErr != noErr)  ExitToShell();
  744.         aeErr = AEInstallEventHandler(kCoreEventClass,
  745.                                        kAEOpenApplication,
  746.                                        (EventHandlerProcPtr) AEOpenHandler,
  747.                                        0, FALSE);
  748.         if (aeErr != noErr) ExitToShell();
  749.         aeErr = AEInstallEventHandler(kCoreEventClass,
  750.                                        kAEOpenDocuments,
  751.                                        (EventHandlerProcPtr) AEOpenDocHandler,
  752.                                        0, FALSE);
  753.         if (aeErr != noErr) ExitToShell();
  754.         aeErr = AEInstallEventHandler(kCoreEventClass,
  755.                                        kAEQuitApplication,
  756.                                        (EventHandlerProcPtr) AEQuitHandler,
  757.                                        0, FALSE);
  758.         if (aeErr != noErr) ExitToShell();
  759.         aeErr = AEInstallEventHandler(kCoreEventClass,
  760.                                        kAEPrintDocuments,
  761.                                        (EventHandlerProcPtr) AEPrintHandler,
  762.                                        0, FALSE);
  763.         if (aeErr != noErr) ExitToShell();
  764.         aeErr = AESetInteractionAllowed(kAEInteractWithAll);
  765.         if (aeErr != noErr)  ExitToShell();
  766.     }
  767.     else
  768.         ExitToShell();
  769. }
  770.  
  771.  
  772. void     BuildMenuBar(void)
  773. {
  774. //    Construct a menu bar for our application. (Yawn)
  775.  
  776.     theMenuBar = GetNewMBar(kMBarID);
  777.     SetMenuBar(theMenuBar);
  778.     appleMenu = GetMHandle(kAppleMenu);
  779.     fileMenu = GetMHandle(kFileMenu);
  780.     editMenu = GetMHandle(kEditMenu);
  781.     AddResMenu(appleMenu, 'DRVR');
  782.     DrawMenuBar();
  783. }
  784.  
  785.  
  786. void     InitProgram(void)
  787. {
  788. //    Initialize the Macintoshâ„¢ Toolbox and application
  789. //    environment.
  790.  
  791.     quitting = FALSE;
  792.     background = FALSE;
  793.     MaxApplZone();
  794.     InitGraf(&qd.thePort);
  795.     InitFonts();
  796.     InitWindows();
  797.     InitMenus();
  798.     TEInit();
  799.     InitDialogs(NIL);
  800.     InitCursor();
  801.     
  802.     InitAEStuff();
  803.     BuildMenuBar();
  804. }
  805.  
  806.  
  807. void     Idling(void)
  808. {
  809. //    We don't do anything while idling. Perhaps we should sing a song?
  810. }
  811.  
  812.  
  813. void     InvokeDA(MenuHandle theMenu, long theItem)
  814. {
  815. //    Bring up a desk accessory.
  816.  
  817.     OSErr            err;
  818.     Str255            da;
  819.  
  820.     GetItem(theMenu, theItem, da);
  821.     err = OpenDeskAcc(da);
  822. }
  823.  
  824.  
  825. void     MenuCommand(long theCmd)
  826. {
  827. //    Activate the appropriate menu item.
  828.  
  829.     long            menuID, menuItem;
  830.     int                dontCare;
  831.  
  832.     menuID = HiWord(theCmd);
  833.     menuItem = LoWord(theCmd);
  834.     switch (menuID ) {
  835.         case kAppleMenu:
  836.             if (menuItem != 1)  InvokeDA(appleMenu, menuItem);
  837.             else dontCare = Alert(666, NIL);
  838.             break;
  839.         case kFileMenu:
  840.             quitting = TRUE;
  841.             break;
  842.         case kEditMenu: break;
  843.     }
  844.     HiliteMenu(0);
  845. }
  846.  
  847.  
  848. void     DispatchMouseDown(EventRecord theEvent)
  849. {
  850. //    Dispatch a mouse down event to the proper handler.
  851.  
  852.     WindowPtr            theWindow;
  853.  
  854.     switch (FindWindow(theEvent.where, &theWindow)) {
  855.         case inMenuBar:
  856.             MenuCommand(MenuSelect(theEvent.where));
  857.             break;
  858.         case inSysWindow:
  859.             SystemClick(&theEvent, theWindow);
  860.             break;
  861.         case inDrag:
  862.             if (theWindow == FrontWindow())
  863.                 DragWindow(theWindow, theEvent.where, &qd.screenBits.bounds);
  864.             break;
  865.         case inContent: case inDesk: case inGrow: case inGoAway: 
  866.             break;
  867.     }
  868. }
  869.  
  870.  
  871. void     DispatchKeyDown(EventRecord theEvent)
  872. {
  873. //    Dispatch a key down event to the proper handler. Since typing
  874. //    isn't supported, the routine only checks for service key equivalents.
  875.  
  876.     char            key;
  877.  
  878.     key = theEvent.message & charCodeMask;
  879.     if ((theEvent.modifiers & cmdKey) && (theEvent.what == keyDown))
  880.         MenuCommand(MenuKey(key));
  881. }
  882.  
  883.  
  884. void     ActivateWindow(WindowPtr, Boolean)
  885. {
  886. //    Gee, we don't have any windows worth activating.
  887. }
  888.  
  889.  
  890. void     UpdateWindow(WindowPtr)
  891. {
  892. //    Gee, we don't have any windows worth updating.
  893. }
  894.  
  895. void     DiskInserted(long diskInfo)
  896. {
  897. //    Handle disk insert errors.
  898.  
  899.     Point        where;
  900.     OSErr        dontCare;
  901.  
  902.     if (HiWord(diskInfo) != noErr) {
  903.         SetPt(&where, 40, 40);
  904.         dontCare = DIBadMount(where, diskInfo);
  905.     }
  906. }
  907.  
  908.  
  909. void     DispatchOSEvent(EventRecord theEvent)
  910. {
  911. //    Dispatch OS events.
  912.  
  913.     switch ((theEvent.message >> 24) & 0x0FF) {
  914.         case kMouseMovedMessage:
  915.             Idling();
  916.             break;
  917.         
  918.         case kSuspendResumeMessage:
  919.             background = (theEvent.message & resumeFlag);
  920.             ActivateWindow(FrontWindow(), !background);
  921.             break;
  922.     }
  923. }
  924.  
  925.  
  926. void     DispatchHighEvent(EventRecord theEvent)
  927. {
  928. //    Send off those Apple Events!
  929.  
  930.     aeError = AEProcessAppleEvent(&theEvent);
  931. }
  932.